/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.version;

import cn.easyplatform.entities.EntityInfo;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.GetEntryCmd;
import cn.easyplatform.studio.cmd.version.CheckCmd;
import cn.easyplatform.studio.cmd.version.ImportCmd;
import cn.easyplatform.studio.utils.StudioUtil;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.utils.ZipUtil;
import cn.easyplatform.studio.vos.IXVo;
import cn.easyplatform.studio.web.editors.AbstractPanelEditor;
import cn.easyplatform.studio.web.editors.Editor;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import cn.easyplatform.type.EntityType;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.*;

import java.util.Iterator;
import java.util.List;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class ImportEditor extends AbstractPanelEditor {
    private String id;

    private Label baseline;

    private Label project;

    private Label operator;

    private Label date;

    private Label size;

    private Label comment;

    private Grid grid;

    private Button check;

    private Button commit;

    private IXVo entity;

    public ImportEditor(WorkbenchController workbench, String id) {
        super(workbench, id);
        this.id = id;
    }

    @Override
    public void create(Object... args) {
        String key = "editor.import.title";
        String image = "~./images/svn/import.gif";
        if (Editor.ROOTTASK_IMPORT_REPO_ID.equals(id)) {
            key = "menu.repo.import.main.entity";
            image = "~./images/action.gif";
        }
        Idspace is = createPanel(Labels.getLabel(key), image, "~./include/editor/version/import.zul");
        for (Component comp : is.getFellows()) {
            String id = comp.getId();
            if (id.equals("versionImport_label_baseline")) {
                this.baseline = (Label) comp;
            } else if (id.equals("versionImport_label_project")) {
                this.project = (Label) comp;
            } else if (id.equals("versionImport_label_operator")) {
                this.operator = (Label) comp;
            } else if (id.equals("versionImport_label_date")) {
                this.date = (Label) comp;
            } else if (id.equals("versionImport_label_comment")) {
                this.comment = (Label) comp;
            } else if (id.equals("versionImport_label_size")) {
                this.size = (Label) comp;
            } else if (id.equals("versionImport_grid_commit")) {
                this.grid = (Grid) comp;
            } else if (id.equals("versionImport_button_check")) {
                this.check = (Button) comp;
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (id.equals("versionImport_button_commit")) {
                this.commit = (Button) comp;
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (id.equals("versionImport_button_upload")) {
                comp.addEventListener(Events.ON_UPLOAD, this);
            }
        }
    }

    private void redraw(IXVo vo) {
        this.entity = vo;
        baseline.setValue(vo.getFirstNo() + "-" + vo.getLastNo());
        project.setValue(vo.getProjectId());
        operator.setValue(vo.getUser());
        date.setValue(DateFormatUtils.format(vo.getDate(), "yyyy-MM-dd hh:mm:ss"));
        size.setValue((vo.getEntities() != null ? vo.getEntities().size(): "0") + "");
        comment.setValue(vo.getDesp());
        for (EntityInfo s : vo.getEntities()) {
            Row li = new Row();
            li.appendChild(new Label(s.getId()));
            li.appendChild(new Label(s.getName()));
            li.appendChild(new Label(s.getDescription()));
            li.appendChild(new Label(s.getType()));
            li.appendChild(new Label(s.getUpdateDate().toString()));
            li.appendChild(new Label(s.getUpdateUser()));
            li.appendChild(new Label(s.getVersion() + ""));
            Hlayout div = new Hlayout();
            div.setSpacing("6px");
            A del = new A();
            del.setZclass("btn btn-danger btn-xs");
            del.setIconSclass("z-icon-times");
            del.setTooltiptext(Labels.getLabel("button.remove"));
            del.addEventListener(Events.ON_CLICK, this);
            A check = new A();
            check.setZclass("btn btn-primary btn-xs");
            check.setIconSclass("z-icon-eye");
            check.setTooltiptext(Labels.getLabel("editor.import.compare"));
            check.addEventListener(Events.ON_CLICK, this);
            div.appendChild(check);
            div.appendChild(del);
            li.appendChild(div);
            li.setValue(s);
            grid.getRows().appendChild(li);
        }
        //check.setDisabled(false);
        //commit.setDisabled(false);
    }

    @Override
    public void dispatch(Event event) {
        if (event.getName().equals(Events.ON_UPLOAD)) {
            UploadEvent ue = (UploadEvent) event;
            try {
                byte[] data = ue.getMedia().getByteData();
                IXVo vo = (IXVo) ZipUtil.unpackZip(data);
                if (vo != null) {
                    grid.getRows().getChildren().clear();
                    redraw(vo);
                    check.setDisabled(false);
                    commit.setDisabled(false);
                }
            } catch (Exception e) {
                WebUtils.showError(Labels.getLabel("import.editor.error.file"));
            }
            //((Button) ue.getTarget()).setDisabled(true);
        } else if (event.getName().equals(Events.ON_CLICK)) {
            if (event.getTarget() == check) {
                if (check())
                    WebUtils.showSuccess(Labels.getLabel("editor.import.check.ok"));
            } else if (event.getTarget() == commit) {
                commit();
            } else if (event.getTarget().getNextSibling() == null) {//remove
                remove(event.getTarget());
            } else {//compare
                compare(event.getTarget());
            }
        }
    }

    private boolean check() {
        List<EntityInfo> entities = StudioApp.execute(check, new CheckCmd(entity.getEntities(), entity.getId()));
        if (!entities.isEmpty()) {
            int size = entities.size();
            for (Component c : grid.getRows().getChildren()) {
                Row li = (Row) c;
                EntityInfo s = li.getValue();
                Iterator<EntityInfo> itr = entities.iterator();
                while (itr.hasNext()) {
                    EntityInfo e = itr.next();
                    if (s.getId().equals(e.getId())) {
                        ((Label) li.getFirstChild()).setSclass("btn-danger");
                        itr.remove();
                        break;
                    }
                }
                if (entities.isEmpty())
                    break;
            }
            WebUtils.showError(Labels.getLabel("editor.import.check.error", new Object[]{size}));
            return false;
            //Clients.showNotification(Labels.getLabel("editor.import.check.error", new Object[]{size}), Clients.NOTIFICATION_TYPE_ERROR, check, "start_before", -1, false);
        } else
            return true;
            //Clients.showNotification(Labels.getLabel("editor.import.check.ok"), Clients.NOTIFICATION_TYPE_INFO, check, "start_before", -1, false);
    }

    private void commit() {
        if (check() == true) {
            if (StudioApp.execute(commit, new ImportCmd(entity))) {
                WebUtils.showSuccess(Labels.getLabel("editor.import.commit.ok"));
                //Clients.showNotification(Labels.getLabel("editor.import.commit.ok"), Clients.NOTIFICATION_TYPE_INFO, commit, "start_before", -1, false);
                /*commit.setDisabled(true);
                check.setDisabled(true);*/
            }
        }
    }

    private void remove(final Component c) {
        WebUtils.showConfirm(Labels.getLabel("button.remove"), new EventListener<Event>() {
            @Override
            public void onEvent(Event event) throws Exception {
                if (event.getName().equals(Events.ON_OK)) {
                    Row row = (Row) c.getParent().getParent();
                    EntityInfo e = row.getValue();
                    entity.getEntities().remove(e);
                    row.detach();
                }
            }
        });
    }

    private void compare(Component c) {
        Row row = (Row) c.getParent().getParent();
        final EntityInfo e = row.getValue();
        EntityInfo orig = StudioApp.execute(c, new GetEntryCmd(e.getId()));
        if (orig != null) {
            AbstractView.createVersionView(new EditorCallback<String>() {
                @Override
                public String getValue() {
                    if (e.getType().equals(EntityType.REPORT.getName()))
                        return StudioUtil.convertReportContent(e.getContent());
                    return e.getContent();
                }

                @Override
                public void setValue(String value) {
                }

                @Override
                public String getTitle() {
                    return Labels.getLabel("entity.content.compare", new String[]{e.getId()});
                }

                @Override
                public Page getPage() {
                    return baseline.getPage();
                }

                @Override
                public Editor getEditor() {
                    return ImportEditor.this;
                }
            }, orig.getType().equals(EntityType.REPORT.getName()) ? StudioUtil.convertReportContent(orig.getContent()) :
                    orig.getContent()).doOverlapped();
        }
    }

}
